lispy = {
    SOI ~
    expr_or_init_expr ~ whitespace? ~
    EOI
}

whitespace = _{(" " | "\t" | "\n" | "\n\r")+}

expr_or_init_expr = {init_expr | value | compound_expr}
expr_start = {"("}
expr_end = {")"}

expr = {value | compound_expr}

compound_expr = {
    expr_start ~
    whitespace? ~

    minimum_expr ~
    (whitespace ~ operator ~ whitespace ~ expr)* ~

    whitespace? ~
    expr_end
}

minimum_expr = {expr ~ whitespace ~ operator ~ whitespace ~ expr}

init_expr = {
    minimum_expr ~
    (whitespace ~ operator ~ whitespace ~ expr)*
}

operator = {
  "add" | "+" |
  "sub" | "-" |
  "mul" | "*" |
  "div" | "/" |
  "mod" | "%"
}

value = {number}

number = {
    (algebraic_sign? ~ ASCII_DIGIT+ ~ decimal_dot ~ ASCII_DIGIT+) |
    (algebraic_sign ~ ASCII_DIGIT+) |
    (algebraic_sign? ~ decimal_dot ~ ASCII_DIGIT+) |
    ASCII_DIGIT+
}

algebraic_sign = {
    ("-"+ | "+")
}

decimal_dot = {
    "."
}
